import os
import smtplib
import uuid
from datetime import datetime
from email.header import Header
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
from scripts.handle_file import HandleFile
import yaml

from config import settings
from utils.parse_config import conf
from log.logUtils import logger

'''
运维提供内容 ：  

邮箱地址: no-reply@53zaixian.com
SMTP 地址: smtp.feishu.cn
SMTP 密码: S5BzC3dqBIQkY06J
SMTP 端口号（SSL）: 465
SMTP 端口号（starttls）: 587
'''

my_sender = conf.getconf('Email', 'smtp_email_address')
my_user = 'yongweiye@53zaixian.com'
my_host = conf.getconf('Email', 'smtp_server_host')
my_pass = conf.getconf('Email', 'smtp_server_pass')
smtp_starttls_port = conf.getconf('Email', 'smtp_starttls_port')
smtp_ssl_port = conf.getconf('Email', 'smtp_ssl_port')


def test_MIMEText_text():
    msg = MIMEText('Python 邮件发送测试- 普通文本测试 ：' + uuid.uuid1().__doc__, 'plain', 'utf-8')
    # msg['From'] = formataddr(('nick1', my_sender))  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
    # message['From'] = Header("nick2", 'utf-8')  # 括号里的对应发件人邮箱昵称（随便起）、发件人邮箱账号
    # message['To'] = Header("test", 'utf-8')  # 括号里的对应收件人邮箱昵称、收件人邮箱账号

    msg['From'] = my_sender
    msg['To'] = my_user
    # msg['To'] = formataddr(('小伙伴', my_user))  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
    msg['Subject'] = Header('普通文本测试', 'utf-8')
    smtpObj = smtplib.SMTP_SSL(my_host, 465)
    smtpObj.login(my_sender, my_pass)
    smtpObj.sendmail(my_sender, my_user, msg.as_string())
    logger.info("邮件发送成功")


def test_MIMEText_html():
    mail_msg = """
    <p>Python 邮件发送测试...</p>
    <p><a href="http://www.runoob.com">这是一个链接</a></p>
    """
    msg = MIMEText(mail_msg, 'html', 'utf-8')
    msg['From'] = my_sender
    msg['To'] = my_user
    # msg['To'] = formataddr(('小伙伴', my_user))  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
    msg['Subject'] = Header('普通文本测试', 'utf-8')
    smtpObj = smtplib.SMTP_SSL(my_host, 465)
    smtpObj.login(my_sender, my_pass)
    smtpObj.sendmail(my_sender, my_user, msg.as_string())
    logger.info("邮件发送成功")


def test_MIMEText_Image():
    mail_msg = """
        <p>Python 邮件发送测试...</p>
        <p><a href="http://www.runoob.com">这是一个链接</a></p>
        """

    # msg = MIMEText(mail_msg, 'html', 'utf-8')
    msg = MIMEMultipart('related')

    msgAlternative = MIMEMultipart('alternative')
    msg.attach(msgAlternative)
    mail_msg = """
    <p>APIAutomatormation 邮件发送报告集成样式图测试...</p>
    <p><a href="http://10.0.20.38">报告地址</a></p>
    <p>携带图片测试：</p>
    <p><img src="cid:image1"></p>
    """
    msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))

    # 指定图片为当前目录

    fp = open(settings.LOADDING_PICTURE, 'rb')
    msgImage = MIMEImage(fp.read())
    fp.close()

    # 定义图片 ID，在 HTML 文本中引用
    msgImage.add_header('Content-ID', '<image1>')
    msg.attach(msgImage)

    msg['From'] = my_sender
    msg['To'] = my_user
    # msg['To'] = formataddr(('小伙伴', my_user))  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
    msg['Subject'] = Header('超文本测试', 'utf-8')
    smtpObj = smtplib.SMTP_SSL(my_host, 465)
    smtpObj.login(my_sender, my_pass)
    smtpObj.sendmail(my_sender, my_user, msg.as_string())
    logger.info("邮件发送成功")
    pass


def test_MIMEText_Attachment():
    msg = MIMEMultipart()

    # 邮件正文内容
    msg.attach(MIMEText('这是多附件测试发送 邮件发送测试……', 'plain', 'utf-8'))
    # 构造附件1，传送当前目录下的 test.txt 文件
    att1 = MIMEText(open('../resource/test.txt', 'rb').read(), 'base64', 'utf-8')
    att1["Content-Type"] = 'application/octet-stream'
    # 这里的filename可以任意写，写什么名字，邮件中显示什么名字
    att1["Content-Disposition"] = 'attachment; filename="test.txt"'
    msg.attach(att1)

    # 构造附件2，传送当前目录下的 runoob.txt 文件
    att2 = MIMEText(open('../resource/runnob.txt', 'rb').read(), 'base64', 'utf-8')
    att2["Content-Type"] = 'application/octet-stream'
    att2["Content-Disposition"] = 'attachment; filename="runoob.txt"'
    msg.attach(att2)

    msg['From'] = my_sender
    msg['To'] = my_user
    # msg['To'] = formataddr(('小伙伴', my_user))  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
    msg['Subject'] = Header('多附件测试发送', 'utf-8')
    smtpObj = smtplib.SMTP_SSL(my_host, 465)
    smtpObj.login(my_sender, my_pass)
    smtpObj.sendmail(my_sender, my_user, msg.as_string())
    logger.info("邮件发送成功")


def test_MIMEText_MIX():
    # todo
    '''
    暂未调通该方法
    :return:  None
    '''
    # 通过Header对象编码的文本，包含utf-8编码信息和Base64编码信息。以下中文名测试ok
    # subject = '中文标题'
    # subject=Header(subject, 'utf-8').encode()

    # 构造文字内容

    msg = MIMEMultipart('mixed')
    text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.baidu.com"
    text_plain = MIMEText(text, 'plain', 'utf-8')
    msg.attach(text_plain)

    # 构造图片链接
    sendimagefile = open(settings.LOADDING_PICTURE, 'rb').read()
    image = MIMEImage(sendimagefile)
    image.add_header('Content-ID', '<image1>')
    image["Content-Disposition"] = 'attachment; filename="testimage.png"'
    msg.attach(image)

    # 构造html
    # 发送正文中的图片:由于包含未被许可的信息，网易邮箱定义为垃圾邮件，报554 DT:SPM ：<p><img src="cid:image1"></p>
    html = """
    <html>  
      <head></head>  
      <body>  
        <p>Hi!<br>  
           How are you?<br>  
           Here is the <a href="http://www.baidu.com">link</a> you wanted.<br> 
        </p> 
      </body>  
    </html>  
    """
    text_html = MIMEText(html, 'html', 'utf-8')
    text_html["Content-Disposition"] = 'attachment; filename="index.html"'
    msg.attach(text_html)

    # 构造附件
    sendfile = open('../resource/test.txt', 'rb').read()
    text_att = MIMEText(sendfile, 'base64', 'utf-8')
    text_att["Content-Type"] = 'application/octet-stream'
    # 以下附件可以重命名成aaa.txt
    # text_att["Content-Disposition"] = 'attachment; filename="aaa.txt"'
    # 另一种实现方式
    text_att.add_header('Content-Disposition', 'attachment', filename='aaa.txt')
    # 以下中文测试不ok
    # text_att["Content-Disposition"] = u'attachment; filename="中文附件.txt"'.decode('utf-8')
    msg.attach(text_att)

    # msg['To'] = formataddr(('小伙伴', my_user))  # 括号里的对应收件人邮箱昵称、收件人邮箱账号

    msg['Subject'] = Header('多附件测试发送 ', 'utf-8')
    smtpObj = smtplib.SMTP_SSL(my_host, 465)
    smtpObj.set_debuglevel(1)
    smtpObj.login(my_sender, my_pass)
    smtpObj.sendmail(my_sender, my_user, msg.as_string())


class SendEMail(object):
    """封装发送邮件类"""

    def __init__(self, smtp_server_host='smtp.feishu.cn', smtp_ssl_port=465,
                 smtp_email_address='no-reply@53zaixian.com', smtp_server_pass='S5BzC3dqBIQkY06J'):
        # 第一步：连接到smtp服务器
        self.smtpObj = smtplib.SMTP_SSL(host=smtp_server_host,
                                        port=smtp_ssl_port)
        # 第二步：登陆smtp服务器
        self.smtpObj.login(user=smtp_email_address,
                           password=smtp_server_pass)

    def send_text(self, from_user, to_user, content, subject):
        """
        发送文本邮件
        :param to_user: 对方邮箱
        :param content: 邮件正文
        :param subject: 邮件主题
        :return:
        """
        # 第三步：准备邮件
        # 使用email构造邮件
        msg = MIMEText(content, _subtype='plain', _charset="utf8")
        # 添加发件人
        msg["From"] = from_user
        # 添加收件人
        msg["To"] = to_user
        # 添加邮件主题
        # msg["subject"] = subject
        msg["subject"] = Header(subject, 'utf-8')
        # 第四步：发送邮件
        self.smtpObj.sendmail(from_addr=from_user, to_addrs=to_user, msg=msg.as_string())

    def send_file(self, from_user, to_user, content, subject, reports_path, file_name):
        """
        发送测试报告邮件
        :param to_user: 对方邮箱
        :param content: 邮件正文
        :param subject: 邮件主题
        :param reports_path: 测试报告路径(完整文件路径名称)
        :param file_name: 发送时测试报告名称
        """
        # 读取报告文件中的内容
        file_content = open(reports_path, "rb").read()
        # 2.使用email构造邮件
        # （1）构造一封多组件的邮件
        msg = MIMEMultipart()
        # (2)往多组件邮件中加入文本内容
        text_msg = MIMEText(content, _subtype='plain', _charset="utf8")
        msg.attach(text_msg)
        # (3)往多组件邮件中加入文件附件
        file_msg = MIMEApplication(file_content)
        file_msg.add_header('content-disposition', 'attachment', filename=file_name)
        msg.attach(file_msg)
        # 添加发件人
        msg["From"] = from_user
        # 添加收件人
        msg["To"] = to_user
        # 添加邮件主题
        msg["subject"] = subject
        # 第四步：发送邮件
        self.smtpObj.sendmail(from_addr=from_user, to_addrs=to_user, msg=msg.as_string())

class HandleEmail():

    def __init__(self, host="smtp.qq.com", port=25, *args, **kwargs):
        self.host = host
        self.port = port

    # 添加文本
    def add_text(self, text):
        return MIMEText(text, "plain", "utf-8")

    # 添加html文本
    def add_html_text(self, html):
        return MIMEText(html, "html", "utf-8")

    # 添加附件,图片，txt,pdf,zip
    def add_accessory(self, filepath):
        res = MIMEText(open(filepath, "rb").read(), "base64", "utf-8")
        res.add_header('Content-Disposition','attachment',filename=os.path.basename(filepath))
        return res
        # 添加主题 发件人，收件人

    def add_subject_attach(self, send_email, receiver, subject, sender, attach_info:tuple, send_date=None):
        """

        @param send_email: 发送方email
        @param receiver:  接收方email群发是列表形式 ["xxx@qq.com",XXXX@qq.com,....]
        @param subject: 邮件主题
        @param sender: 发送发的名字，一般指测试人员
        @param attach_info: 构建附件元组
        @param send_date: 发送日期，"%Y-%m-%d %H:%M:%S"，当为None时用当前时间发送邮件
        @return: msg 可以传给 send_email(）方法发送邮件
        """

        msg = MIMEMultipart('mixed')
        msg['Subject'] = subject
        # msg['From'] = '{0} <{1}>'.format(datas["send_email"][send_email][0], send_email)
        msg['From'] = '{0} <{1}>'.format(sender, send_email)
        msg['To'] = ";".join(receiver)
        if send_date:
            msg['Date'] = send_date
        else:
            msg['Date'] = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")
        if isinstance(attach_info, tuple):
            for i in attach_info:
                msg.attach(i)
        return msg


    def send_email(self, send_email, pwd, receiver, msg):
        try:
            smtp = smtplib.SMTP(self.host, port=self.port)
            smtp.login(send_email, pwd)
            smtp.sendmail(send_email, receiver, msg.as_string())
            print("{0}给{1}发送邮件成功,发送时间:{2}".format(send_email, receiver,
                                                  datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")))
        except Exception as e:
            print('SMTP Exception:\n' + str(e) + '\n')
            raise e
        finally:
            smtp.quit()

    def send_allure_email(self,send_email,subject, report_name, send_date=None, text="本邮件由系统自动发出，无需回复！\n各位同事，大家好，以下为本次测试报告."):
        """
        此方法是为公司定制发送Outputs/allure_reports的测试报告打包 群发到邮件
        数据读写的是configs/emailcof.yaml中的数据
        @param send_email: 发送方的邮件
        @param subject:  主题 格式字符串
        @param report_name: 测试报告名字  字符串
        @param send_date: 日期 字符串 %Y-%m-%d %H:%M:%S
        @param text: 正文文本
        @return: None
        """
        # ------加载conf/emailconf.yaml 数据----
        EMAIL_CONF_FILE_PATH = ''
        with open(EMAIL_CONF_FILE_PATH, "r") as f:
            datas = yaml.load(f, Loader=yaml.FullLoader)  # Loader=yaml.FullLoader 去除警告
            print(datas)
        try:
            sender = datas["send_email"][send_email][0]
            pwd = datas["send_email"][send_email][1]
            receiver = datas["receiver"]
        except Exception as err:
            print("ERROR：\n"+str(err)+"\n")
            print(f"请检查是否有将{send_email}添加到emailconf配置文件里")

        # 添加文本内容
        text = text
        text_plain = self.add_text(text)
        # 先将ALLURE_REPORTS_DIR打包成zip再发送附件
        t = datetime.strftime(datetime.now(), "%Y%m%d%H%M%S_")
        ALLURE_REPORTS_DIR = ''
        file_package_path = os.path.join(ALLURE_REPORTS_DIR, f"{t}{report_name}")
        allure_report = HandleFile.make_package(file_package_path, "zip", ALLURE_REPORTS_DIR)
        # 添加附件
        zip_allure = self.add_accessory(allure_report)
        # 构建附件元组
        attach_info = (text_plain, zip_allure)

        # 添加主题,附件信息 添加到msg
        msg = self.add_subject_attach(send_email, receiver, subject,sender, attach_info=attach_info,send_date=send_date)
        # 发送邮件
        self.send_email(send_email, pwd, receiver, msg)

    def send_public_email(self,send_email, receiver, pwd, sender, subject, send_date=None, text="",hmtl="",filepath=None):
        attach_info = []
        text_plain = self.add_text(text=text)
        attach_info.append(text_plain)
        if hmtl:
            text_html = self.add_html_text(hmtl=hmtl)
            attach_info.append(text_html)
        elif filepath :
            file_attach = self.add_accessory(filepath=filepath)
            attach_info.append(file_attach)
        # 构建附件元组
        attach_info = tuple(attach_info)
        # 添加主题和附件信息到msg
        msg = self.add_subject_attach(send_email,receiver,subject,sender,attach_info=attach_info,send_date=send_date)
        # 发送邮件
        self.send_email(send_email, pwd, receiver, msg)




'''
if __name__ == '__main__':
    # HandleEmail().send_allure_email("17740xxxx@qq.com", "这是一封全国最帅男人的告白", "allure_测试报告")
    send_email = "17740xxxx@qq.com"
    receiver = ['33052xxx@qq.com','17740xxxx@qq.com','13752xxx@qq.com','renxxx@126.com']
    pwd = "mgoiscexxxx"
    sender = "寧·我劝你善良"
    subject = "善良哥哥就是帅"
    text = "我就是那么帅，走到哪里都有风.\n闾阎扑地，钟鸣鼎食之家.\n舸舰弥津，青雀黄龙之舳.\n云销雨霁，彩彻区明。落霞与孤鹜齐飞，秋水共长天一色.\n"
    filepath = r"I:\python20\softwaredate\py_basics\13邮件\pycharm_win快捷键.png"
    HandleEmail().send_public_email(send_email, receiver, pwd, sender, subject, send_date=None, text=text,hmtl="",filepath=filepath)
    pass
'''

if __name__ == '__main__':
    def running_smtp_starttls_port():
        '''
            SMTP 端口号（starttls）: 587
        '''
        str = r" Traceback (most recent call last): +\
          File C://Users//Administrator//OneDrive//2018//Desktop//WorkStation//Email//Email - 副本.py, line 39, in <module>+\
            sendmail(from_email,password,to_email,testing,How are you!)+\
          File C://Users//Administrator//OneDrive//2018//Desktop//WorkStation//Email//Email - 副本.py, line 20, in sendmail+\
            server.starttls()+\
          File C:\Users\Administrator\Anaconda3\lib\smtplib.py, line 749, in starttls+\
            self.ehlo_or_helo_if_needed()+\
          File C:\Users\Administrator\Anaconda3\lib\smtplib.py, line 603, in ehlo_or_helo_if_needed+\
            raise SMTPHeloError(code, resp)+\
        smtplib.SMTPHeloError: (501, b5.5.4 Invalid domain name [HK2PR03CA0047.apcprd03.prod.outlook.com])+\
        "

        # msg = MIMEText('vrdjo', 'plain', 'utf-8')

        msg = MIMEText(str + uuid.uuid1().__doc__, 'plain', 'utf-8')
        # msg['From'] = formataddr(('若水', my_sender))  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg['From'] = my_sender
        msg['To'] = my_user
        # msg['To'] = formataddr(('小伙伴', my_user))  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg['Subject'] = "SMTP 端口号（starttls）: 测试"  # 邮件的主题，也可以说是标题

        server = smtplib.SMTP(my_host, smtp_starttls_port)
        server.starttls()
        server.ehlo()
        server.login(my_sender, my_pass)
        server.sendmail(msg['From'], msg['To'], msg.as_string())
        server.close()


    # for i  in range(1,3):
    #     running_test1()
    def running_smtp_ssl_port():
        '''
        使用SMTP 端口号（SSL）: 465
        :return:
        '''

        message = MIMEText("使用加密的SMTP协议测试下邮件", 'plain', 'utf-8')
        subject = u'SMTP WITH SSL'
        message['From'] = my_sender
        message['To'] = my_user
        message['Subject'] = Header(subject, 'utf-8')
        smtpObj = smtplib.SMTP_SSL(my_host, 465)
        smtpObj.login(my_sender, my_pass)
        smtpObj.sendmail(my_sender, my_user, message.as_string())
        logger.info("邮件发送成功")


    running_smtp_ssl_port()

    # server = smtplib.SMTP()
    # server.connect("smtp.feishu.cn")
    # server.starttls()
    # server.login(my_sender, "S5BzC3dqBIQkY06J")
    # server.sendmail(my_sender, my_user, msg.as_string())
    # server.quit()
    pass

# smtpObj = smtplib.SMTP()
# smtpObj.connect("smtp.feishu.cn", 465)  # 25 为 SMTP 端口号
# smtpObj.login("no-reply@53zaixian.com", "S5BzC3dqBIQkY06J")
# smtpObj.sendmail('no-reply@53zaixian.com', 'yongweiy@53zaixian.com', 'yongweiy@53zaixian.com')


# smtp.login('no-reply@53zaixian.com', 'S5BzC3dqBIQkY06J')
# smtp.ehlo()  # 向邮箱发送SMTP 'ehlo' 命令
# logger.info("111111111")
# smtp.starttls()
# smtp.sendmail('no-reply@53zaixian.com', 'yongweiye@53zaixian.com', 'demo')
# smtp.close()
#
# smtp = smtplib.SMTP('smtp.feishu.cn', 465)
# smtp.ehlo()
# smtp.starttls()
# smtp.login('no-reply@53zaixian.com', 'S5BzC3dqBIQkY06J')
# smtp.sendmail('smtp.feishu.cn', 'yongweiy@53zaixian.com', "message")


'''
#coding: utf-8    
  
import smtplib    
from email.mime.multipart import MIMEMultipart    
from email.mime.text import MIMEText    
from email.mime.image import MIMEImage 
from email.header import Header   
    
#设置smtplib所需的参数
#下面的发件人，收件人是用于邮件传输的。
smtpserver = 'smtp.163.com'
username = 'XXX@163.com'
password='XXX'
sender='XXX@163.com'
#receiver='XXX@126.com'
#收件人为多个收件人
receiver=['XXX@126.com','XXX@126.com']

subject = 'Python email test'
#通过Header对象编码的文本，包含utf-8编码信息和Base64编码信息。以下中文名测试ok
#subject = '中文标题'
#subject=Header(subject, 'utf-8').encode()
    
#构造邮件对象MIMEMultipart对象
#下面的主题，发件人，收件人，日期是显示在邮件页面上的。
msg = MIMEMultipart('mixed') 
msg['Subject'] = subject
msg['From'] = 'XXX@163.com <XXX@163.com>'
#msg['To'] = 'XXX@126.com'
#收件人为多个收件人,通过join将列表转换为以;为间隔的字符串
msg['To'] = ";".join(receiver) 
#msg['Date']='2012-3-16'

#构造文字内容   
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.baidu.com"    
text_plain = MIMEText(text,'plain', 'utf-8')    
msg.attach(text_plain)    

#构造图片链接
sendimagefile=open(r'D:\pythontest\testimage.png','rb').read()
image = MIMEImage(sendimagefile)
image.add_header('Content-ID','<image1>')
image["Content-Disposition"] = 'attachment; filename="testimage.png"'
msg.attach(image)

#构造html
#发送正文中的图片:由于包含未被许可的信息，网易邮箱定义为垃圾邮件，报554 DT:SPM ：<p><img src="cid:image1"></p>
html = """
<html>  
  <head></head>  
  <body>  
    <p>Hi!<br>  
       How are you?<br>  
       Here is the <a href="http://www.baidu.com">link</a> you wanted.<br> 
    </p> 
  </body>  
</html>  
"""    
text_html = MIMEText(html,'html', 'utf-8')
text_html["Content-Disposition"] = 'attachment; filename="texthtml.html"'   
msg.attach(text_html)    


#构造附件
sendfile=open(r'D:\pythontest\1111.txt','rb').read()
text_att = MIMEText(sendfile, 'base64', 'utf-8') 
text_att["Content-Type"] = 'application/octet-stream'  
#以下附件可以重命名成aaa.txt  
#text_att["Content-Disposition"] = 'attachment; filename="aaa.txt"'
#另一种实现方式
text_att.add_header('Content-Disposition', 'attachment', filename='aaa.txt')
#以下中文测试不ok
#text_att["Content-Disposition"] = u'attachment; filename="中文附件.txt"'.decode('utf-8')
msg.attach(text_att)    
       
#发送邮件
smtp = smtplib.SMTP()    
smtp.connect('smtp.163.com')
#我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。
#smtp.set_debuglevel(1)  
smtp.login(username, password)    
smtp.sendmail(sender, receiver, msg.as_string())    
smtp.quit()
'''
